home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
User's Choice Windows CD
/
User's Choice Windows CD (CMS Software)(1993).iso
/
misc1
/
iv26_w30.zip
/
SOURCES
/
WPAINT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-18
|
15KB
|
667 lines
/*
* MS Windows - dependent code
*/
#include <Interviews\bitmap.h>
#include <Interviews\paint.h>
#include <Interviews\defs.h>
#include <Interviews\X11\worldrep.h>
#include <InterViews\X11\palette.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <dir.h>
#include <stdio.h>
#include <fstream.h>
char* Stock_Fonts[] = { { "ANSI_FIXED_FONT" },
{ "ANSI_VAR_FONT" },
{ "DEVICE_DEFAULT_FONT" },
{ "OEM_FIXED_FONT" },
{ "SYSTEM_FONT" } };
/*
******************** class Brush *************************
*/
BrushRep::BrushRep (int* pattern, int c, int width) {
count = c;
if (c != 0) {
info = new int[count];
for (int i = 0; i < count; ++i) {
*(info + i) = pattern[i];
}
}
}
BrushRep::~BrushRep () {
if ((info != nil) && (count != 0)) {
delete info;
}
}
/*
************************** class Color *********************************
*/
boolean ColorRep::ScanColorFile (
const char* name, ColorIntensity& r, ColorIntensity& g, ColorIntensity& b
) {
char *file, *ptr;
char color[30];
char buf[50];
FILE* source;
boolean result = false;
r = 0; g = 0; b = 0;
if ((file = searchpath("colors.ali")) == 0) {
return result;
}
source = fopen(file, "r");
/*
* Der Farbstring wird in einen String, wie ihn "colors.ali" verwendet,
* umgwandelt.
*/
for (int j = 0, i = 0; i < strlen(name); i++) {
if (name[i] != ' ') {
color[j++] = tolower(name[i]);
}
}
color[j] = ' ';
color[j+1] = '\0';
/*
* "Colors.ali" wird auf Vorhandensein des Strings überprüft.
* Erfolg wird dann gemeldet, wenn der String in einer Zeile
* zu finden ist, und wenn er an der ersten Position der Zeile
* beginnt (d.h. er ist nicht Teilstring einer anderen Farbe, wie
* z.B. "blue" von "mediumblue").
*/
while (!feof(source)) {
fgets(buf, 50, source);
if ((ptr = strstr(buf, color)) != NULL && ptr == buf) {
char* tmp;
tmp = strtok(buf, " ");
tmp = strtok(NULL, " ");
r = atoi(tmp);
tmp = strtok(NULL, " ");
g = atoi(tmp);
tmp = strtok(NULL, " \n\0");
b = atoi(tmp);
result = true;
break;
}
}
fclose(source);
return result;
}
inline unsigned MakeXIntensity (unsigned i) {
return ((i << 8) + i);
}
inline unsigned MakeWinIntensity (unsigned i) {
return (i >> 8);
}
ColorRep::ColorRep (
ColorIntensity r, ColorIntensity g, ColorIntensity b
) {
red = MakeWinIntensity(r);
green = MakeWinIntensity(g);
blue = MakeWinIntensity(b);
pixel = _palette->SetEntry(red, green, blue);
}
ColorRep::ColorRep (
long p, ColorIntensity& r, ColorIntensity& g, ColorIntensity& b
) {
r = GetRValue(p);
g = GetGValue(p);
b = GetBValue(p);
pixel = _palette->SetEntry(r, g, b);
red = r; green = g; blue = b;
r = MakeXIntensity(red);
g = MakeXIntensity(green);
b = MakeXIntensity(blue);
}
ColorRep::ColorRep (
const char* name, ColorIntensity& r, ColorIntensity& g, ColorIntensity& b
) {
if (ScanColorFile(name, red, green, blue)) {
pixel = _palette->SetEntry(red, green, blue);
} else {
pixel = 0;
}
r = MakeXIntensity(red);
g = MakeXIntensity(green);
b = MakeXIntensity(blue);
}
ColorRep::~ColorRep () {
/*** aus Palette entfernen ***/
}
int ColorRep::GetPixel () {
return pixel;
}
void ColorRep::GetIntensities (
ColorIntensity& r, ColorIntensity& g, ColorIntensity& b
) {
r = red;
g = green;
b = blue;
}
/*
****************************** class Font ***********************
*/
FontRep::FontRep () {
height = 0;
id = nil;
}
FontRep::~FontRep() {
}
boolean FontRep::IsStockFont (const char* f) {
char tmp[FONTSTRINGSIZE];
int stock_font = -1;
strcpy(name, f);
strcpy(tmp, name);
if (strcmpi(tmp, Stock_Fonts[0]) == 0) {
stock_font = ANSI_FIXED_FONT;
} else if (strcmpi(tmp, Stock_Fonts[1]) == 0) {
stock_font = ANSI_VAR_FONT;
} else if (strcmpi(tmp, Stock_Fonts[2]) == 0) {
stock_font = DEVICE_DEFAULT_FONT;
} else if (strcmpi(tmp, Stock_Fonts[3]) == 0) {
stock_font = OEM_FIXED_FONT;
} else if (strcmpi(tmp, Stock_Fonts[4]) == 0) {
stock_font = SYSTEM_FONT;
}
if (stock_font != -1) {
id = (void*)GetStockObject(stock_font);
return true;
}
return false;
}
void Font::GetFontByName (const char* name) {
if (!rep->IsStockFont(name)) {
rep->MakeNewFont(name);
}
}
Font::~Font () {
Unref(rep);
}
void FontRep::GetFontString (char** fontstring) {
FILE* source;
char buf[FONTSTRINGSIZE];
char str[FONTSTRINGSIZE];
char *file, *ptr;
int num_substrs = 0;
char* substrs[13];
boolean result;
(*fontstring)[0] = '\0';
//
// Der String mit den Wildcards wird in diejenigen Teilstrings
// aufgespalten, die im eigentlichen Fontstring enthalten sein müssen.
//
strcpy(str, name);
if ((substrs[num_substrs] = strtok(str, "*\0")) != NULL) {
num_substrs++;
}
while ((substrs[num_substrs] = strtok(NULL, "*\0")) != NULL) {
num_substrs++;
}
//
// Es wird Zeile für Zeile der Fontdatenbank gelesen und auf Vorkommen
// der Teilstrings untersucht. Die erste Zeile, die alle Teilstrings
// enthält, ist der eigentliche Fontstring.
//
file = searchpath("fonts.dir");
if (file == 0) {
return;
}
source = fopen(file, "r");
while (!feof(source)) {
fgets(buf, FONTSTRINGSIZE, source);
result = true;
ptr = buf;
for (int i = 0; i < num_substrs; i++) {
if ((ptr = strstr(ptr, substrs[i])) == NULL) {
result = false;
break;
}
ptr++;
}
if (result) {
strcpy((*fontstring), buf);
break;
}
}
fclose(source);
}
unsigned char FontRep::GetLogFontCharSet () {
char tmp[LF_FACESIZE];
BYTE char_set = ANSI_CHARSET;
strcpy(tmp, typeface);
if (strcmpi(typeface, "terminal") == 0 ||
strcmpi(typeface, "modern") == 0 ||
strcmpi(typeface, "roman") == 0 ||
strcmpi(typeface, "script") == 0 ) {
char_set = OEM_CHARSET;
}
return char_set;
}
void FontRep::GetLogFontTypeFace (char* ptr) {
ifstream source;
char buf[128];
char *p, *file;
strcpy(typeface, ptr);
if ((file = searchpath("fonts.tfc")) == 0) {
return;
}
source.open(file, ios::nocreate);
while (!source.eof()) {
source.getline(buf, 128);
if (strstr(buf, typeface)) {
p = strchr(buf, '@') + 1;
strcpy(typeface, p);
source.close();
return;
}
}
source.close();
}
boolean FontRep::GetLogFont (void* logfont) {
char* buffer = new char[FONTSTRINGSIZE];
char* ptr;
int value;
LPLOGFONT lf = (LPLOGFONT)logfont;
strcpy(buffer, name);
GetFontString(&buffer);
if (buffer[0] == '\0') {
return false;
}
/* Foundry */
if ((ptr = strtok(buffer, "-")) != NULL);
/* Font Family */
if ((ptr = strtok(NULL, "-")) != NULL) {
GetLogFontTypeFace(ptr);
for (int i = 0; i <= strlen(typeface); i++) {
lf->lfFaceName[i] = typeface[i];
}
}
lf->lfCharSet = GetLogFontCharSet();
/* Weight */
lf->lfWeight = 400;
if ((ptr = strtok(NULL, "-")) != NULL) {
if (!strcmpi(ptr, "bold")) {
lf->lfWeight = 700;
}
}
/* Slant */
lf->lfItalic = 0;
if ((ptr = strtok(NULL, "-")) != NULL) {
if (!strcmpi(ptr, "i") || !strcmpi(ptr, "o")) {
lf->lfItalic = 1;
}
}
/* Set Width */
if ((ptr = strtok(NULL, "-")) != NULL);
/* Pixels */
lf->lfHeight = 0;
if (((ptr = strtok(NULL, "-")) != NULL) && (value = atoi(ptr))) {
lf->lfHeight = value;
}
/* Points */
if ((ptr = strtok(NULL, "-")) != NULL);
/* Hor. Resolution */
if ((ptr = strtok(NULL, "-")) != NULL);
/* Vert. Resolution */
if ((ptr = strtok(NULL, "-")) != NULL);
/* Spacing */
lf->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
if ((ptr = strtok(NULL, "-")) != NULL) {
if (!strcmpi(ptr, "m")) {
lf->lfPitchAndFamily |= FIXED_PITCH;
}
if (!strcmpi(ptr, "p")) {
lf->lfPitchAndFamily |= VARIABLE_PITCH;
}
}
/* Width */
lf->lfWidth = 0;
if ((ptr = strtok(NULL, "-")) != NULL);
/* Character Set */
if ((ptr = strtok(NULL, "-\n")) != NULL);
/* Defaults */
lf->lfEscapement = 0;
lf->lfOrientation = 0;
lf->lfUnderline = 0;
lf->lfStrikeOut = 0;
lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf->lfQuality = DEFAULT_QUALITY;
delete buffer;
return true;
}
void FontRep::GetFontAlias (const char* f) {
ifstream source;
char buf[FONTSTRINGSIZE];
char *ptr, *file;
if ((file = searchpath("fonts.ali")) == 0) {
return;
}
source.open(file, ios::nocreate);
while (!source.eof()) {
source.getline(buf, FONTSTRINGSIZE);
if (strstr(buf, f)) {
ptr = &buf[strlen(f)];
while (*ptr == ' ') {
ptr++;
}
strcpy(name, ptr);
return;
}
}
source.close();
}
boolean FontRep::GetFontResource (char** font_resource) {
ifstream source;
char buf[128];
char *ptr, *file;
if ((file = searchpath("fonts.rsc")) == 0) {
return false;
}
source.open(file, ios::nocreate);
while (!source.eof()) {
source.getline(buf, 128);
if (strstr(buf, typeface)) {
ptr = strchr(buf, '@') + 1;
strcpy(*font_resource, ptr);
source.close();
return true;
}
}
source.close();
return false;
}
void FontRep::MakeNewFont (const char* font) {
char* font_res = new char[13];
LOGFONT logFont;
id = (void*)GetStockObject(SYSTEM_FONT);
strcpy(name, font);
GetFontAlias(font);
if (GetLogFont(&logFont)) {
if (GetFontResource(&font_res)) {
if (AddFontResource(font_res)) {
id = (void*)CreateFontIndirect(&logFont);
}
}
}
delete font_res;
}
int Font::Baseline () {
TEXTMETRIC metrics;
int result = 0;
HDC hDC = _world->hdc();
HFONT holdFont = nil;
if (Valid()) {
holdFont = SelectObject(hDC, (HFONT)Id());
}
if (GetTextMetrics(hDC, (LPTEXTMETRIC)&metrics)) {
result = metrics.tmDescent;
}
if (holdFont != nil) {
SelectObject(hDC, holdFont);
}
return result;
}
int Font::Width (const char* s) {
return Width(s, strlen(s));
}
int Font::Width (const char* s, int len) {
int result, length;
HDC hDC = _world->hdc();
length = strlen(s);
if (length > len) {
length = len;
}
HFONT holdFont;
holdFont = SelectObject(hDC, (HFONT)Id());
result = GetTextExtent(hDC, (LPSTR)s, length);
SelectObject(hDC, holdFont);
return result;
}
int Font::Height () {
TEXTMETRIC tm;
int result;
HDC hDC = _world->hdc();
HFONT holdFont = SelectObject(hDC, (HFONT)rep->id);
GetTextMetrics(hDC, &tm);
result = tm.tmHeight;
SelectObject(hDC, holdFont);
return result;
}
int Font::Index (const char* s, int len, int offset, boolean between) {
const char* p;
int n, w;
int coff, cw;
HDC hDC = _world->hdc();
HFONT holdFont = nil;
holdFont = SelectObject(hDC, (HFONT)Id());
if (offset < 0 || *s == '\0' || len == 0) {
return 0;
}
w = 0;
for (p = s, n = 0; *p != '\0' && n < len; ++p, ++n) {
w += GetTextExtent(hDC, (LPSTR)s, n+1);
cw = GetTextExtent(hDC, (LPSTR)p, 1);
// w += cw;
if (w > offset) {
break;
}
coff = offset - w;
}
if (between && coff > cw/2) { // der Index, der am nächsten zu offset
++n;
}
SelectObject(hDC, holdFont);
return min(++n, len);
}
boolean Font::FixedWidth () {
LOGFONT logFont;
if (Valid()) {
GetObject((HFONT)Id(), sizeof(logFont), (LPSTR)&logFont);
if (logFont.lfPitchAndFamily & FIXED_PITCH) {
return true;
}
}
return false;
}
/*
************************** class Pattern ***********************
*/
/*
int _xpos = 0;
int _ypos = 400;
void _DisplayBitmap(void* map, int width, int height) {
WNDCLASS wc;
wc.style = NULL;
wc.lpfnWndProc = DefWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = _world->hinstance();
wc.lpszMenuName = NULL;
wc.lpszClassName = "iii";
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
HBRUSH bg = CreateSolidBrush(RGB(0, 0, 255));
wc.hbrBackground = bg;
RegisterClass(&wc);
HWND hWnd = CreateWindow(
"iii",
"Bitmap",
WS_BORDER,
_xpos,
_ypos,
50,
80,
NULL,
NULL,
_world->hinstance(),
NULL
);
_xpos += 50;
if (_xpos >= 600) {
_xpos = 0;
_ypos += 80;
}
if (hWnd) {
void* c;
c = (void*)hWnd;
ShowWindow((HWND)c, SW_SHOW);
}
HDC hDC = GetDC(hWnd);
HDC hMemDC = CreateCompatibleDC(hDC);
HBITMAP holdBitmap = SelectObject(hMemDC, (HBITMAP)map);
BitBlt(hDC, 5, 5, width, height, hMemDC, 0, 0, SRCCOPY);
SelectObject(hMemDC, holdBitamp);
DeleteDC(hMemDC);
ReleaseDC(hWnd, hDC);
}
*/
#ifdef bitmap_h
HBITMAP GetInvertedBitmap (Bitmap* b) {
HBITMAP hBitmap = CreateBitmap(b->Width(), b->Height(), 1, 1, NULL);
HDC hMemDC = CreateCompatibleDC(_world->hdc());
HDC hMemDC1 = CreateCompatibleDC(_world->hdc());
HBITMAP holdBitmap = SelectObject(hMemDC, (HBITMAP)b->Map());
HBITMAP holdBitmap1 = SelectObject(hMemDC1, hBitmap);
PatBlt(hMemDC1, 0, 0, b->Width(), b->Height(), BLACKNESS);
BitBlt(hMemDC1, 0, 0, b->Width(), b->Height(), hMemDC, 0, 0, SRCINVERT);
SelectObject(hMemDC1, holdBitmap1);
SelectObject(hMemDC, holdBitmap1);
DeleteDC(hMemDC1);
DeleteDC(hMemDC);
return hBitmap;
}
Pattern::Pattern (Bitmap* b) {
HBITMAP hBitmap = GetInvertedBitmap(b);
info = (void*)CreatePatternBrush(hBitmap);
DeleteObject(hBitmap);
}
Pattern::Pattern (int p[patternHeight]) {
int newp[patternHeight];
for (int i = 0; i < patternHeight; i++) {
newp[i] = ~p[i];
}
HBITMAP hBitmap = CreateBitmap(8, 8, 1, 1, (LPSTR)newp);
info = (void*)CreatePatternBrush(hBitmap);
DeleteObject(hBitmap);
}
Pattern::Pattern (int dither) {
int i, seed;
short int r[8];
seed = dither;
for (i = 0; i < 4; i++) {
r[i] = (seed & 0xf000) >> 12;
r[i] |= r[i] << 4;
r[i] |= r[i] << 8;
seed <<= 4;
r[i] = ~r[i];
r[i+4] = r[i];
}
HBITMAP hBitmap = CreateBitmap(8, 8, 1, 1, (LPSTR)r);
info = (void*)CreatePatternBrush(hBitmap);
DeleteObject(hBitmap);
}
Pattern::~Pattern () {
if (info != nil) {
DeleteObject((HBRUSH)info);
}
}
#endif